package com.js.core.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.js.core.entity.result.EditorResult;
import com.js.core.entity.result.ResultBean;
import com.js.core.entity.SysFile;
import com.js.core.mapper.FileMapper;
import com.js.core.service.FileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;

/**
 * @ClassName FileServiceImpl
 * @Description 文件服务层实现
 * @Author mazp
 * @Date 2025/10/11 15:20
 */
@Service
@Transactional
public class FileServiceImpl extends ServiceImpl<FileMapper, SysFile> implements FileService {

    private static Logger log= LoggerFactory.getLogger(FileServiceImpl.class);

    @Resource
    private FileMapper fileMapper;

    @Override
    public ResultBean upload(MultipartFile file, String type) {
        ResultBean resultBean = new ResultBean();
        SysFile sysFile = buildSysFile(file, type);
        File uploadFile=new File(sysFile.getAbsolutePath());
        //目录不存在则新建
        FileUtil.mkParentDirs(uploadFile);
        //上传
        try {
            file.transferTo(uploadFile);
        } catch (IOException e) {
            log.error("文件上传失败：｛｝", e);
            resultBean.setCode(ResultBean.CODE_ERROR);
            resultBean.setMsg(e.getMessage());
            return resultBean;
        }
        //回传给前端的图片url,/pic/upload/202510/202302066962.JPG
        String urlPath=File.separator +"pic" + File.separator+"upload"+ File.separator +
                LocalDate.now() + File.separator + sysFile.getFileName();
        sysFile.setUrlPath(urlPath);
        sysFile.setFileSize(getPrintSize(file.getSize()));
        fileMapper.insert(sysFile);
        return resultBean.setData(urlPath);
    }


    /**
     * @description  构建需要入库的文件信息
     * @author  mazp
     * @date    2025/10/11 15:36
     * @param	file
     * @param	type
     * @return  com.js.core.entity.SysFile
    */
    public SysFile buildSysFile(MultipartFile file, String type){
        SysFile sysFile = new SysFile();
        String filefullname = file.getOriginalFilename();
        //logger.info("原文件名：{}",filefullname);
        String root= System.getProperty("user.dir");
        //获取拓展名
        String fileExtname = filefullname.substring(filefullname.lastIndexOf(".") + 1).toUpperCase();
        List<String> extList = new ArrayList<String>(Arrays.asList("png", "jpg", "peg", "bmp", "gif", "webp", "psd", "svg", "tiff"));
        for(String str:extList){
            if(str.equalsIgnoreCase(fileExtname)){
                sysFile.setIsShow(true);
                break;
            }else{
                sysFile.setIsShow(false);
            }
        }
        //新文件名
        String newFilename=DateUtil.format(new Date(),"yyyyMMdd")+new Random().nextInt(10000)+'.'+fileExtname;
        //文件全路径(这里不能用@Value去读yml，因为是多模块，service没有yml文件
        String path=root + File.separator  + "upload" + File.separator + LocalDate.now() +File.separator+newFilename;
        sysFile.setAbsolutePath(path);
        sysFile.setOriginalName(filefullname);
        sysFile.setFileName(newFilename);
        sysFile.setFileType(fileExtname);
        sysFile.setType(type);
        sysFile.setCreateBy("模拟登陆用户");
        sysFile.setCreateTime(DateUtil.date());
        return sysFile;
    }

    /**
     * 返回文件大小
     * @param size
     * @return
     */
    static String getPrintSize(long size) {
        // 如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
        if (size < 1024) {
            return size + "B";
        } else {
            size = size / 1024;
        }
        // 如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
        // 因为还没有到达要使用另一个单位的时候
        // 接下去以此类推
        if (size < 1024) {
            return size + "KB";
        } else {
            size = size / 1024;
        }
        if (size < 1024) {
            // 因为如果以MB为单位的话，要保留最后1位小数，
            // 因此，把此数乘以100之后再取余
            size = size * 100;
            return size / 100 + "." + size % 100 + "MB";
        } else {
            // 否则如果要以GB为单位的，先除于1024再作同样的处理
            size = size * 100 / 1024;
            return size / 100 + "." + size % 100 + "GB";
        }
    }
}
